#ifndef VFlowLayout_H
#define VFlowLayout_H

#include "VPageLayout.h"

///////////////////////////////////////////////////////////////////////////////
class VFlowLayout;
///////////////////////////////////////////////////////////////////////////////

class VFlowLayoutLineEdit : public QLineEdit
{
	Q_OBJECT
	
public:
	VFlowLayoutLineEdit(QWidget *parent = NULL);

/*protected:
	virtual void showEvent(QShowEvent* event)
	{
		slotTextChanged();
		QLineEdit::showEvent(event);
	}*/

private slots:
	void slotTextChanged();
	
private:
	int calcWidth() const;
};

///////////////////////////////////////////////////////////////////////////////

class VFlowLayoutTextEdit : public QTextEdit
{
	Q_OBJECT

public:
	enum EWidth
	{
		EWidth_page,
		EWidth_expanding
	};
	
public:
	VFlowLayoutTextEdit(QWidget *parent = 0);

	void setInFlowLayout(bool v);
	bool inFlowLayout() const { return m_inFlowLayout;}
	
	int pageWidth() const;

	void setEWidth(EWidth v) { m_eWidth = v;}
	EWidth eWidth() const { return m_eWidth;}

	QSize calcFixedSize() const;
	QSize calcMaximumSize() const;
	QSize	calcSizeHint() const;
	int calcFontAscent() const;
	
public: // QTextEdit
	virtual QSize	sizeHint() const;
/*	
	virtual QSize minimumSize() const 
	{ 
		return calcSizeHint();
	}
	virtual QSize maximumSize() const 
	{ 
		return calcSizeHint();
	}
*/	
	
protected slots:	
	void slotContentsChanged();
	
private:
	int dH() const { return 4;}
	int dW() const { return 6;}

	EWidth m_eWidth;
	VFlowLayout *m_flowLayout;
	bool m_inFlowLayout;
	friend VFlowLayout;
};

///////////////////////////////////////////////////////////////////////////////

class VFlowLayoutSplitter
{
public:
	VFlowLayoutSplitter(VFlowLayout *flowLayout);

	void splitForWidth(int width,const QList<QLayoutItem*> &itemList = QList<QLayoutItem*>());
	QSize currentSize(const QList<QLayoutItem*> &itemList);
	QSize minimumSize(const QList<QLayoutItem*> &itemList);
	QSize fixedSize(const QList<QLayoutItem*> &itemList);
	void setGeometry(const QRect &rect);
	
private:
	typedef QList<QLayoutItem*> VCols;
	typedef QList<VCols> VRows;

	void calcMaxAscent(const VCols &cols,int &maxAscent,int &wCols);
	QSize sizeHint(QLayoutItem *item) const;
	QSize minimumSize(QLayoutItem *item) const;
	void setGeometry(QLayoutItem *item,const QRect &rect);

	VFlowLayout *m_flowLayout;
	VRows m_rows;
};
typedef QSharedPointer<VFlowLayoutSplitter> VFlowLayoutSplitterPtr;

///////////////////////////////////////////////////////////////////////////////

class VFlowLayoutParams
{
public:
	VFlowLayoutParams() :m_pageLayout(NULL) {}
	
private:
	VPageLayout *m_pageLayout;
	friend VFlowLayout;
};

///////////////////////////////////////////////////////////////////////////////

class VFlowLayout : public QLayout
{
	Q_OBJECT
	
public:
	VFlowLayout(QWidget *parent = NULL);
	~VFlowLayout();

/***************
	void setHorizontalSpacing(int v = 0) { m_hSpacing = v;}
	int horizontalSpacing() const;

	void setVerticalSpacing(int v = 0) { m_vSpacing = v;}
	int verticalSpacing() const;
*****************/

	//void setPageWidth(int v) { m_pageWidth = v;}
	int pageWidth() const;

	QList<QLayoutItem*> itemList() const { return m_itemList;}
	
	void addLayout(QLayout *layout);
	
public:	// QLayout
	virtual void addItem(QLayoutItem *item);
	virtual int count() const { return m_itemList.count();}

	virtual QLayoutItem *itemAt(int index) const;
	virtual QLayoutItem *takeAt(int index);

	virtual Qt::Orientations expandingDirections() const { return 0;} //Qt::Vertical | Qt::Horizontal;}
	virtual bool hasHeightForWidth() const { return true;}
	virtual int heightForWidth(int width) const;
	//virtual int	minimumHeightForWidth(int width) const { return heightForWidth(width);}
	virtual QSize maximumSize() const { return QSize(pageWidth(),QLayout::maximumSize().height());}
	virtual QSize minimumSize() const { return m_splitter->minimumSize(m_itemList);}
	virtual QSize sizeHint() const { return m_splitter->currentSize(m_itemList);}
	virtual void setGeometry(const QRect &rect);
    
protected:
	//int doLayout(const QRect &rect, bool testOnly) const;
	int smartSpacing(QStyle::PixelMetric pm) const;

	QList<QLayoutItem*> m_itemList;
	//QRect m_rect;
	//int m_invalidate;
	int m_hSpacing;
	int m_vSpacing;
	//int m_pageWidth;
	VFlowLayoutParams *m_params;

	VFlowLayoutSplitterPtr m_splitter;
	friend VFlowLayoutSplitter;
};

///////////////////////////////////////////////////////////////////////////////

class VHBoxLayout : public VFlowLayout
{
	Q_OBJECT

public:
	VHBoxLayout(QWidget *parent = NULL) :VFlowLayout(parent) {}

public:	// VFlowLayout
	virtual QSize minimumSize() const { return m_splitter->fixedSize(m_itemList);}
	virtual QSize sizeHint() const { return m_splitter->fixedSize(m_itemList);}
};

///////////////////////////////////////////////////////////////////////////////

#endif
